﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using Microsoft.Win32;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using System.Windows;
using EnvDTE;
using EnvDTE80;
using System.Collections.Generic;

namespace CTX.CtxPackage
{
    /// <summary>
    /// This is the class that implements the package exposed by this assembly.
    ///
    /// The minimum requirement for a class to be considered a valid package for Visual Studio
    /// is to implement the IVsPackage interface and register itself with the shell.
    /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
    /// to do it: it derives from the Package class that provides the implementation of the 
    /// IVsPackage interface and uses the registration attributes defined in the framework to 
    /// register itself and its components with the shell.
    /// </summary>
    // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
    // a package.
    [PackageRegistration(UseManagedResourcesOnly = true)]
    // This attribute is used to register the informations needed to show the this package
    // in the Help/About dialog of Visual Studio.
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
    // This attribute is needed to let the shell know that this package exposes some menus.
    [ProvideMenuResource("Menus.ctmenu", 1)]
    // This attribute registers a tool window exposed by this package.
    [ProvideToolWindow(typeof(MyToolWindow))]
    [Guid(GuidList.guidCtxPackagePkgString)]
    public sealed class CtxPackagePackage : Package
    {
        /// <summary>
        /// Default constructor of the package.
        /// Inside this method you can place any initialization code that does not require 
        /// any Visual Studio service because at this point the package object is created but 
        /// not sited yet inside Visual Studio environment. The place to do all the other 
        /// initialization is the Initialize method.
        /// </summary>
        public CtxPackagePackage()
        {
            Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
        }

        /// <summary>
        /// This function is called when the user clicks the menu item that shows the 
        /// tool window. See the Initialize method to see how the menu item is associated to 
        /// this function using the OleMenuCommandService service and the MenuCommand class.
        /// </summary>
        private void ShowToolWindow(object sender, EventArgs e)
        {
            var dte = (DTE)GetService(typeof(DTE));
            if (dte.Solution != null )
            {
                // Get the instance number 0 of this tool window. This window is single instance so this instance
                // is actually the only one.
                // The last flag is set to true so that if the tool window does not exists it will be created.
                ToolWindowPane window = this.FindToolWindow(typeof(MyToolWindow), 0, true);
                if ((null == window) || (null == window.Frame))
                {
                    throw new NotSupportedException(Resources.CanNotCreateWindow);
                }
                (window as MyToolWindow).DTE = dte;
                (window as MyToolWindow).ServiceProvider = this;
                IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
                Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
            }
        }

        /////////////////////////////////////////////////////////////////////////////
        // Overriden Package Implementation
        #region Package Members

        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initilaization code that rely on services provided by VisualStudio.
        /// </summary>
        protected override void Initialize()
        {
            Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
            base.Initialize();

            // Add our command handlers for menu (commands must exist in the .vsct file)
            OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            if ( null != mcs )
            {
                // Create the command for the menu item.
                CommandID menuCommandID = new CommandID(GuidList.guidCtxPackageCmdSet, (int)PkgCmdIDList.cmdidCtxCommand);
                MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
                mcs.AddCommand( menuItem );
                // Create the command for the tool window
                CommandID toolwndCommandID = new CommandID(GuidList.guidCtxPackageCmdSet, (int)PkgCmdIDList.cmdidCtxTool);
                MenuCommand menuToolWin = new MenuCommand(ShowToolWindow, toolwndCommandID);
                mcs.AddCommand( menuToolWin );
            }
        }
        #endregion
        
        /// <summary>
        /// This function is the callback used to execute a command when the a menu item is clicked.
        /// See the Initialize method to see how the menu item is associated to this function using
        /// the OleMenuCommandService service and the MenuCommand class.
        /// </summary>
        private void MenuItemCallback(object sender, EventArgs e)
        {
            MessageBox.Show("Test");

            // Show a Message Box to prove we were here
            //IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
            //Guid clsid = Guid.Empty;
            
            //// you could refer to: http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/23c4e363-da06-4b9e-916c-9db54bf6bf84
            ////var ProjectType = "{FAE04EC0-301F-11D3-BF4B-00C04F688DDE}";
            ////var ProjectFolderType = ProjectKinds.vsProjectKindSolutionFolder;

            //var dte = (DTE)GetService(typeof(DTE));
            //var solution2 = (Solution2)dte.Solution;
            //var solution2Build = (SolutionBuild2)solution2.SolutionBuild;
            //var projectNames = string.Empty;
            //var allProjects = new List<Project>();

            //foreach (Project project in solution2.Projects)
            //{
            //    if (project.Kind.Equals(ProjectKinds.vsProjectKindSolutionFolder, StringComparison.InvariantCultureIgnoreCase))
            //    {
            //        var solutionFolder = (SolutionFolder)project.Object;
            //        foreach (ProjectItem projectItem in project.ProjectItems)
            //        {
            //            allProjects.Add(projectItem.SubProject);
            //        }
            //    }
            //    else //if (project.Kind.Equals(ProjectType, StringComparison.InvariantCultureIgnoreCase))
            //    {
            //        allProjects.Add(project);
            //    }
            //}

            //var solutionConfiguration = solution2Build.ActiveConfiguration;
            //foreach (var project in allProjects)
            //{
            //    project.Save();
            //}
            ////solution2Build.Clean(true);
            //solution2Build.Build(true);

            //var solutionName = dte.Solution.Properties.Item("Name").Value;
            //var uiHierarchy = dte.ActiveWindow.Object as UIHierarchy;
            ////foreach (var project in allProjects)
            //{
            //    var project = allProjects[1];
            //    uiHierarchy.GetItem(string.Format("{0}\\{1}", solutionName, project.Name)).Select(vsUISelectionType.vsUISelectionTypeSelect);

            //    var outputType = project.Properties.Item("OutputType").Value;

            //    //if (project.Name == "Vision.Cms.Mvc")
            //    {
            //        //project.Properties.Item("GenerateManifests").Value = true;
            //        //project.Properties.Item("SignManifests").Value = true;
            //        //project.Save();
                    

            //        //uiHierarchy.GetItem(string.Format("{0}\\{1}", solutionName, project.Name)).Select(vsUISelectionType.vsUISelectionTypeSelect);
            //        //solution2Build.StartupProjects = new string[] { project.Name };

            //        //var buildConfig = "Debug";
            //        //var publishProfile = "Profile1";
            //        //dte.ExecuteCommand("Build.SolutionConfigurations", buildConfig);
            //        //object customin = new object();
            //        //object customout = new object();
            //        //dte.Commands.Raise("{CB26E292-901A-419C-B79D-49BD45C43929}", 120, publishProfile, customout);
            //        //dte.Commands.Raise("{CB26E292-901A-419C-B79D-49BD45C43929}", 122, customin, customout);
            //        //dte.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Publish");    

            //        //var config2 = solution2Build.ActiveConfiguration as SolutionConfiguration2;
            //        //var configName = String.Format("{0}|{1}", config2.Name, config2.PlatformName);
            //        //solution2Build.BuildProject(configName, project.UniqueName, true);
            //        //solution2Build.PublishProject(project.ConfigurationManager.ActiveConfiguration.ConfigurationName + "|" + project.ConfigurationManager.ActiveConfiguration.PlatformName, project.UniqueName, true);
            //        //ConfigName = configName;
            //        //ProjectUniqueName = project.UniqueName;

                    
                   
            //        //dte.ExecuteCommand("Build.PublishSelection");

            //        //while (solution2Build.PublishState != vsPublishState.vsPublishStateDone)
            //        //{
            //        //    System.Threading.Thread.Sleep(1000);
            //        //} 
            //        //MessageBox.Show(configName+"   "+project.ConfigurationManager.ActiveConfiguration.ConfigurationName);
                     
            //    }
            //}
            //solution2Build.Build(true);
            
            //var events2 = dte.Events as Events2;
            //events2.PublishEvents.OnPublishDone += new _dispPublishEvents_OnPublishDoneEventHandler(PublishEvents_OnPublishDone);

            //PublishProject();

        }
    }

}
